package main

import (
	"errors"
	"fmt"
	"strconv"
)

type MyStack struct {
	maxSize int
	top int
	arr [5]int
}

//压栈
func (s *MyStack) push (val int) (err error) {
	if s.top == s.maxSize {
		err = errors.New("栈满")
		return
	}
	s.arr[s.top] = val
	s.top++
	return
}

//弹栈
func (s *MyStack) pop () (data int, err error){
	if s.isEmpty() {
		err = errors.New("栈空")
		return
	}
	s.top--
	data = s.arr[s.top]
	//将弹出后数组位置数置为0
	s.arr[s.top] = 0
	return
}

//判断栈是否为空
func (s *MyStack) isEmpty () (flag bool){
	if s.top == 0 {
		return true
	}
	return false
}

//判断传入的计算符的优先级
func priority(val int) int {
	if val == '+' || val == '-'{
		return 1
	}else if val == '*' || val == '/' {
		return 2
	}else{
		return 0
	}
}

//判断传入的字符串是数字还是运算符
func isOperator(val int) bool {
	if val == '+' || val == '-' || val == '*' || val == '/'{
		return true
	}else {
		return false
	}
}

//根据传入的数字和运算符进行运算，并将结果返回
func calculate(num1 int, num2 int, val int) int {
	switch val {
		case '+':
			return num1+num2
		case '-':
			return num1-num2
		case '*':
			return num1*num2
		case '/':
			return num1/num2
		default:
			fmt.Println("运算符有误")
			return 0
	}
}


func main() {
	//数栈
	numStack := MyStack{
		maxSize : 5,
		top : 0,
		arr : [5]int{},
	}
	//符号栈
	operateStack := MyStack{
		maxSize : 5,
		top : 0,
		arr : [5]int{},
	}

	exp := "3+200*6-5"
	num1 := 0
	num2 := 0
	result := 0
	operator := 0
	for i:=0;i<len(exp);i++ {
		ch := int(exp[i])
		//fmt.Println(priority(ch))
		// 先判断该字符是否运算符
		if isOperator(ch) {
			/*
				再判断运算符栈是否为空，若为空直接入栈，不为空，判断与栈顶元素的优先级
			若该元素优先级大于等于栈顶元素，则直接入栈，若小于，则从数字栈弹出两个数字，和栈顶运算符运算后将结果压入数栈
			 */
			if operateStack.isEmpty(){
				_ = operateStack.push(ch)
			}else {
				for{
					if priority(operateStack.arr[operateStack.top-1]) >= priority(ch){
						//此处注意两个操作数的顺序，先弹栈的为后
						num2,_ = numStack.pop()
						num1,_ = numStack.pop()
						operator,_ = operateStack.pop()
						result = calculate(num1, num2, operator)
						_ = numStack.push(result)
					}else {
						_ = operateStack.push(ch)
						break
					}
					if priority(operateStack.arr[operateStack.top-1]) <= priority(ch) {
						_ = operateStack.push(ch)
						break
					}
				}
			}
		}else {
			//此处增加判断是否为大于9的数字
			temp := string(ch)
			for i+1<len(exp) && !isOperator(int(exp[i+1])){
				nextCh := exp[i+1]
				temp+=string(nextCh)
				i++
			}

			data, _ := strconv.ParseInt(temp, 10, 64)
			fmt.Println("data = ",data)
			_ = numStack.push(int(data))
		}

	}
	for !operateStack.isEmpty() {
		num2,_ = numStack.pop()
		num1,_ = numStack.pop()
		operator,_  = operateStack.pop()
		result = calculate(num1, num2, operator)
		_ = numStack.push(result)
	}
	result,_ = numStack.pop()
	fmt.Printf("%s = %d", exp, result)
	
}

